package util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Scanner;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

public class Renamer {
	public static String excelPath;
	public static String oldFilePath;
	public static String newFilePath;
	public static String newColName;
	public static String oldColName;
	public static int excelFileNum;
	public static int editNum;

	public static void main(String[] args) {
		
		try {
			System.out.println("说明：\n本程序功能为：按照Excel表格中的要求批量修改文件名称。\nExcel表格中需要填写原始文件名列和修改文件名列，"
					+ "程序将按照修改文件名列中文件名将对应的原始文件名进行重命名操作，\n程序不会直接在源文件上修改，而是将源文件复制一份再修改文件名。"
					+ "\n参数设置要求：所有文件目录为文件夹的路径，而非文件路径，如C:/Windows，而非C:/Windows/1.xls。\n");
			Renamer renamer = new Renamer();
			Scanner scanner = new Scanner(System.in);
			String i = "0";
			while(i.equals("0")){
				System.out.print("参数设置\n输入Excel文件目录：");
				excelPath = scanner.nextLine();
				System.out.print("输入源文件目录：");
				oldFilePath = scanner.nextLine();
				System.out.print("输入文件保存目录：");
				newFilePath = scanner.nextLine();
				System.out.print("输入Excel新文件名列名：");
				newColName = scanner.nextLine();
				System.out.print("输入Excel原始文件名列名：");
				oldColName = scanner.nextLine();
				System.out.println("\n参数设置如下");
				System.out.print("Excel文件路径：" + excelPath);
				System.out.print("\n图片文件路径：" + oldFilePath);
				System.out.print("\n图片保存路径：" + newFilePath);
				System.out.print("\nExcel新文件名列名：" + newColName);
				System.out.print("\nExcel原始文件名列名：" + oldColName);
				System.out.println("\n\n输入1开始，输入0重新设置参数，输入其他字符结束...");
				i = scanner.nextLine();
				if (!i.equals("1") && !i.equals("0")){
					System.exit(0);
				}
			}
			scanner.close();
			System.out.println("修改中...");
			renamer.readExcelAndRenameImg();
			System.out.println("修改完成！");
			System.out.println("共找到"+ excelFileNum + "个Excel文件");
			System.out.println("共修改文件名"+ editNum + "次");
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}

	public void readExcelAndRenameImg() throws Exception {
		int newCol = -1;
		int oldCol = -1;

		File file = new File(excelPath);
		if (!file.exists()) {
			throw new Exception("目录不存在！");
		} else if (!file.isDirectory()) {
			file = file.getParentFile();
		}
		for (File f : file.listFiles()) {
			if(!f.isFile()){
				continue;
			} 
			InputStream is = new FileInputStream(f);
			String fileName = f.getName();
			Workbook workbook = null;
			if (fileName.endsWith(".xls")) {
				workbook = new HSSFWorkbook(is);
				excelFileNum ++;
			} else if (fileName.endsWith(".xlsx")) {
				workbook = new XSSFWorkbook(is);
				excelFileNum ++;
			} else {
				is.close();
				continue;
			}
			
			for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
				Sheet sheet = workbook.getSheetAt(sheetNum);
				if (sheet == null) {
					continue;
				}
				int firstRowNum = sheet.getFirstRowNum();
				int startRowNum = firstRowNum + 1;
				int lastRowNum = sheet.getLastRowNum();
				int firstCellNum = sheet.getRow(firstRowNum).getFirstCellNum();
				int lastCellNum = sheet.getRow(firstRowNum).getLastCellNum();
				Row fistRow = sheet.getRow(firstCellNum);
				
				try {
					for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) {
						String cellValue = getCellValue(fistRow.getCell(cellNum));
						if (cellValue.equals(newColName)) {
							newCol = cellNum;
						} else if (cellValue.equals(oldColName)) {
							oldCol = cellNum;
						}
					}
				
					if(newCol==-1) {
						throw new Exception(f.getName() + "中"+ sheet.getSheetName() +"表里未找到" + newColName + "列");
					}
					if(oldCol == -1) {
						throw new Exception(f.getName() + "中"+ sheet.getSheetName() +"表里未找到" + oldColName + "列");
					}
				
					for (int rowNum = startRowNum; rowNum <= lastRowNum; rowNum++) {
						Row row = sheet.getRow(rowNum);
						if (row == null) {
							continue;
						}
						String newName = getCellValue(row.getCell(newCol));
						String oldName = getCellValue(row.getCell(oldCol));
						try {
							copyFile(oldFilePath +File.separator + oldName, newFilePath);
							renameFile(newFilePath + File.separator + oldName, newName);
						} catch (Exception e) {
							System.out.println(e.getMessage());
							continue;
						}
						editNum ++;
						//System.out.println(newName + "," + oldName);
					}
				} catch ( Exception e) {
					System.out.println(e.getMessage());
					continue;
				}

				/*
				 * System.out.println("firstRow:" + firstRowNum);
				 * System.out.println("startRow:" + startRowNum);
				 * System.out.println("lastRow:" + lastRowNum);
				 * System.out.println("firstCell:" + firstCellNum);
				 * System.out.println("lastCell:" + lastCellNum);
				 * System.out.println("col1: " + col1 + " col2: " + col2);
				 */
			}
			is.close();
			workbook.close();
		}
	}

	public static String getCellValue(Cell cell) {
		String cellValue = "";
		if (cell == null) {
			return cellValue;
		}
		// 把数字当成String来读，避免出现1读成1.0的情况
		if (cell.getCellTypeEnum() == CellType.NUMERIC) {
			cell.setCellType(CellType.STRING);
		}
		// 判断数据的类型
		switch (cell.getCellTypeEnum()) {
		case NUMERIC: // 数字
			cellValue = String.valueOf(cell.getNumericCellValue());
			break;
		case STRING: // 字符串
			cellValue = String.valueOf(cell.getStringCellValue());
			break;
		case BOOLEAN: // Boolean
			cellValue = String.valueOf(cell.getBooleanCellValue());
			break;
		case FORMULA: // 公式
			cellValue = String.valueOf(cell.getCellFormula());
			break;
		case BLANK: // 空值
			cellValue = "";
			break;
		case ERROR: // 故障
			cellValue = "非法字符";
			break;
		default:
			cellValue = "未知类型";
			break;
		}
		return cellValue;
	}

	public void copyFile(String srcPath, String desPath) throws Exception {
		File srcFile = new File(srcPath);
		File desFile = new File(desPath);
		if (!srcFile.exists()) 
			throw new Exception(srcFile.getName()+"不存在！" +"（文件路径：" + srcPath + "）");
		if (!desFile.exists())
			desFile.mkdirs();
		if (desFile.isFile())
			desFile = desFile.getParentFile();
		if (srcFile.isFile()) {
			File objFile = new File(desFile.getPath() + File.separator + srcFile.getName());
			// 复制文件到目标地
			InputStream ins = new FileInputStream(srcFile);
			FileOutputStream outs = new FileOutputStream(objFile);
			byte[] buffer = new byte[1024 * 512];
			int length;
			while ((length = ins.read(buffer)) != -1) {
				outs.write(buffer, 0, length);
			}
			ins.close();
			outs.flush();
			outs.close();
		} else {
			throw new Exception("一次只能复制单个文件！");
		}
			
	}

	public void renameFile(String filePath, String newName) throws Exception {
		File file = new File(filePath);
		if (!file.exists()) {
			throw new Exception(file.getName()+"不存在！" +"（文件路径：" + filePath + "）");
		}
		int index = file.getName().lastIndexOf(".");
		String newPath = "";
		if (index > 0) {
			newPath = file.getParent() + File.separator + newName + file.getName().substring(index);
		} else {
			newPath = file.getParent() + File.separator + newName;
		}
		File newFile = new File(newPath);
		if (newFile.exists()) {
			throw new Exception(newName + "已存在！");
		}
		file.renameTo(newFile);
	}
}
